Enter
Программирование Web Devel Базы данных Исходники Photoshop Хостинг Форум
На главную
CodeNet
Все для программиста !
И не только !
Поиск


  Стоит бывать


  ...Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.

"Вирусы", "Черви", "Драконы" и резиденты на службе прогресса.

Назад | Далее

гл.15    В КОТОРОЙ ВЫ УЗНАЕТЕ О ПРОКЛЯТИИ MSDOS --  БУТОВЫХ ВИРУСАХ
                        (совершенно новая тема)
============================================================================

     СРАЗУ ЖЕ ПРЕДУПРЕДИМ ВАС, что работа в данной области сопряжена  с повы-
шенной опасностью. => Вы  должны,  если решитесь что-либо предпринять, прояв-
лять крайнюю осторожность.
     Вот какие минимальные  правила техники безопасности мы бы Вам рекомендо-
вали: при помощи программы diskeditor  из  нортоновских  утилит перепишите на
специальную дискету (в  виде файлов) такие  объекты ЖЕСТКОГО ДИСКА  как  Boot
Record и Partition Table (они придставлены в меню diskeditor-а). Если Вы слу-
чайно повредите эти объекты во время своего эксперимента, при помощи  того же
diskeditor-а (предварительно загрузившись  с  системной дискеты) Вы можете их
восстановить (записать соответствующие  файлы в область Boot Record или MBR).
Более того, когда Вы вольно работаете с прерыванием 13h, иногда полезно быва-
ет сохранять подобным образом даже FAT.

     Расскажем, не вдаваясь в излишние  подробности  о  логической  структуре
жесткого диска (HDD).  HDD разбит на разделы, называемые логическими дисками.
На каждом из  разделов в принципе  может обитать своя  операционная  система.
Каждый такой раздел имеет  специальный  загрузочный сектор, который, в случае
если раздел имеет свою систему, хранит программу ее  загрузки. Кроме разделов
HDD имеет специальный трэк (дорожку),  не доступный  для пользователя MS-DOS;
т.н. скрытый трэк.
     А как PC узнает, на каком из разделов находится система и как он ее заг-
рузит? Дело  в том, что на скрытом трэке, в самом его начале (цилиндр 0, сто-
рона 0, сектор 1) находится специальная крохотная программа-загрузчик (Master
Boot-Record (MBR)), которая анализирует, -  какой  из  разделов имеет систему
(является  активным)   и   передает   управление   загрузчику  этой  системы.
     Теперь по-подробнее, -- как происходит процесс загрузки PC.
     1) Вы включили электропитание;
     2) Специальные подпрограммы BIOS-а, сидящие в ПЗУ, тестируют память
        и прочее железо;
     3) Специальная подпрограмма BIOS-а считала с HDD самый первый сектор
        скрытого трэка (MBR) и передела ей управление. (MBR была считана
        по адресу 0000:7C00h);
     4) MBR хранит в себе специальную таблицу (Partition Table), в которой
        говорится, на каком из разделов HDD сидит система;
        MBR анализирует эту таблицу, определяет активный раздел, после чего
     5) MBR считывает в память (по адресу 0000:7C00h) загрузчик системы,
        (он находится на диске в начале соответствующего раздела) и передает
        ему управление;
     6) Загрузчик системы (Boot Record (BR)) загружает в память системные
        файлы и передает им управление;
     7) далее  инициализируются  драйверы  из  config.sys;  запускается
        COMMAND.COM и стартует autoexec.bat;

     Достаточно долгий и нудный процесс. Но бутовые вирусы себя особо  не ут-
руждают. Когда бутовый вирус заражает  компьютер,  он  переписывает либо MBR,
либо -- BR в какое-либо другое место (как правило -- в пределах скрытого трэ-
ка), а сам -- садится на их место. Когда в  следующий  раз включат зараженный
PC, при  выполнении  пункта  3 (или 5) вместо MBR (или BR) в память по адресу
0000:7C00h будет считан и получит управление вирус. Он  по специальному меха-
низму посадит  резидент и после этого загрузит по  адресу 0000:7C00h MBR (или
BR) и передаст ей управление. Вирус как бы вклинился в процесс загрузки; стал
в нем посредником.
     Чаще вирусы нападают на  BR, нежели на MBR. Это связано с  рядом причин.
Во-первых в процессе загрузки системы к MBR обращаются  не единожды (читаются
данные из Partition Table); т.о. вирус, либо должен оставить в неприкосновен-
ности  Partition  Table,  либо  --  включить  в  свою  резидентную  процедуру
СТЭЛС-блок, каждый  раз, когда идет  запрос на чтение сектора 001, подсовыва-
ющий сохраненную где-то  истинную MBR. Во-вторых даже при визуальном контроле
(если вы  загрузитесь с  системной дискеты и посмотрите на  сектор 001) в MBR
легче обнаружить присутствие  вируса, т.к. "здоровая" MBR занимает лишь около
1/3 сектора, остальное -- пустота.
     Встает вопрос: каким образом бутовые вирусы заражают PC? Есть 2 способа.
Во-первых вирус может быть не чисто бутовым, а бутово-файловым; т.е. заражать
как MBR (BR), так и EXE- и COM-файлы. С компьютера на компьютер он переносит-
ся в  файле. Во-первых вирус может внедряться в  Boot Record-ы гибких дисков.
Пользователь нередко забывает извлечь дискету из  дисковода перед перезагруз-
кой PC. Если это  случится, PC пробует загрузить систему с дискеты.  Тут-то и
вылезает вирус.
     Теперь опишем механизм посадки резидента (он отличается от всех рассмот-
ренных нами ранее).
     Мы уже пользовались областью данных BIOS. В ячейке  с адресом 0040:0134h
мы хранили флажок наличия резидентной копии вируса в памяти. Но помимо пустых
ячеек, которые  мы можем использовать в своих целях,  область данных BIOS со-
держит ячейки, хранящие очень важную информацию. В наших изысканиях нас будет
интересовать ячейка с  адресом  0000:0413h. Здесь хранится величина свободной
памяти PC (одно слово). Выражается эта величина в килобайтах. В момент, когда
файлы MS-DOS загружаются в память, загрузка эта выполняется с учетом величины
свободной памяти.  Если перед началом  загрузки DOS уменьшить слово по адресу
0000:0413h, то после загрузки память будет  распределена  так,  что  появится
свободная область, потерянная для DOS.  Ее  размер = величине, на которую  мы
уменьшили слово по адресу 0000:0413h (в килобайтах). В эту область мы и можем
посадить наш резидент. Весь фрагмент посадки резидента будет выглядеть так:


      XOR   AX,AX                         ;¬
      MOV   DS,AX                         ;¦DS=0
      MOV   AX,word ptr DS:[0413h]        ;¦уменьшаем количество свободной
      DEC   AX                            ;¦памяти на 1  Kб
      MOV   word ptr DS:[0413h],AX        ;-
      ;
      MOV   CL,06                         ;¬вычисляем сегментный адрес
      SHL   AX,CL                         ;+свободного участка памяти
      MOV   ES,AX                         ;-
      ;
      MOV   AX,rezident_segment           ;¬
      MOV   DS,AX                         ;¦пересылаем в захваченную
      MOV   SI,rezident_offset            ;¦нами область код резидента
      XOR   DI,DI                         ;¦ (здесь это - 1 Кб)
      MOV   CX,0100h                      ;¦
      CLD                                 ;¦
      REPNE MOVSW                         ;-


     Ниже мы приводим программу, которая является,  по-сути, фильтром предох-
раняющим компьютер от  бутовых вирусов. Этот фильтр, подобно бутовому вирусу,
записывается (но  только  не  сам по себе, а -- программистом) в сектор 0 0 1
(MBR при этом заблаговременно перемещается нами в  сектор 0  0  7). В  момент
загрузки фильтр  сажает резидент на  прерывание 13h. Как только бутовый вирус
попытается  заразить  PC  (будет дано прерывание 13h -- запись в сектор 0 0 1
или 0  1  1) -- фильтр приостановит работу PC  и выдаст предупреждение. После
этого   PC    будет    автоматически    перезагружен   при   помощи   команды
JMP__far_0FFFF0000h (по этому адресу находится подпрограмма BIOS, осуществля-
ющая перезагрузку). Фильтр реализует стэлс-механизм сектора 0 0 1 (при попыт-
ке считать оттуда информацию мы получаем истинную MBR).
     Вот блок/схема программы:

      --инициализационная часть-¬         _/блок обработки прерывания 13h\_
-------------------------------------¬  -------------------------------------¬
¦ установка стека: SS=0, SP=7C00h    ¦  ¦ читаеся сектор 0 0 1 HDD? если да -¦
¦(сам код начинается по 0000:7C00h)  ¦  ¦подсовываем вместо него сектор 0 0 7¦
L-----------------T-------------------  ¦(истинную MBR,загодя там сохраненную)
                  ¦                     L-----------------T-------------------
------------------+------------------¬                    ¦
¦ уменьшаем слово по адресу 0:413h   ¦  ------------------+------------------¬
L-----------------T-------------------  ¦кто-то пытается что-то записать в   ¦
                  ¦                     ¦сектор 0 0 1? да -- идем на объявле-¦
------------------+------------------¬  ¦ние тревоги >>-----------------------¬
¦ пересылаем резидент в освободив-   ¦  L-----------------T-------------------¦
¦ шуюся область                      ¦                    ¦                   ¦
L-----------------T-------------------  ------------------+------------------¬¦
                  ¦                     ¦кто-то пытается что-то записать в   ¦¦
------------------+------------------¬  ¦сектор 0 1 1? нет - идем на IRET >>--¦¬
¦ делаем JMP far на продолжение кода ¦  L-----------------T-------------------¦¦
¦ уже в резиденте                    ¦                    ¦<-------------------¦
L-----------------T-------------------  ------------------+------------------¬ ¦
                  ¦                     ¦ объявление тревоги и перезагрузка  ¦ ¦
------------------+------------------¬  ¦ PC (JMP far FFFF0000h)             ¦ ¦
¦ перехватываем вектор прерывания    ¦  L------------------------------------- ¦
¦ 13h                                ¦               -----------¬<--------------
L-----------------T-------------------               ¦   IRET   ¦
                  ¦                                  L-----------
------------------+------------------¬
¦ считываем по адресу 0000:7C00h     ¦
¦ истинную MBR (она была записана    ¦
¦ в сектор 0 0 7)                    ¦
L-----------------T-------------------
                  ¦
------------------+------------------¬
¦ делаем JMP far на 0000:7C00h       ¦
¦ (отдаем управл-е истинной MBR)     ¦
L-------------------------------------

     Довольно-таки простая конструкция.
     А вот и сама программа:


      -----------------------------------------------------------¬
      ¦                         пример 22                        ¦:
      L-----------------------------------------------------------

TITLE   Это - COM. программа N23 -- примитивный антивирусный фильтр
ASSUME        CS:CodeSegment
;-------------------------------------------------------------------------
CodeSegment   SEGMENT PARA
              ORG(100h)
Start:
MainProcedure PROC NEAR
              ;
              ;                                   ;внимание! -- при имплан-
              ;                                   ;  тации в область MBR
              ;                                   ;  сектор должен заканчиваться
              ;                                   ;  сигнатурой  55AAh
              ;                                   ;
Code_begining:CLI                                 ;¬  установка стека:
              XOR   AX,AX                         ;+SS:SP = 0000:7C00
              MOV   SS,AX                         ;¦
              MOV   SP,7C00h                      ;-
              MOV   SI,SP                         ;SI = 7C00
              MOV   DS,AX                         ;DS = 0
              STI
              ;
              MOV   AX,word ptr DS:[0413h]        ;¬уменьшаем количество сво-
              DEC   AX                            ;¦  бодной  памяти на 1  Kб
              MOV   word ptr DS:[0413h],AX        ;-
              MOV   CL,06                         ;¬вычисляем сегментный адрес
              SHL   AX,CL                         ;¦свободного участка памяти
              MOV   ES,AX                         ;-
              XOR   DI,DI                         ;DI = 0
              MOV   CX,0100h                      ;¬пересылаем в захваченную
              CLD                                 ;+нами область код резидента
              REPNE MOVSW                         ;- (здесь это - 1 Кб)
              ;
              PUSH  ES                            ;¬
              MOV   AX,Continue_work-Code_begining;+JMP Far на продолжение
              PUSH  AX                            ;¦  кода уже в резиденте
              RETF                                ;-
              ;
              ;-------перехват вектора прерывания 13h----------------------¬
Continue_work:MOV   AX,word ptr DS:[4Ch]                                   ¦
              MOV   word ptr ES:[jmp_old_int13-Code_begining+1],AX         ¦
              MOV   AX,word ptr DS:[4Eh]                                   ¦
              MOV   word ptr ES:[jmp_old_int13-Code_begining+3],AX         ¦
              CLI                                                          ¦
              MOV   word ptr DS:[4Ch],Resident13_begining-Code_begining    ¦
              MOV   word ptr DS:[4Eh],ES                                   ¦
              STI                                                          ¦
              ;-------------------------------------------------------------
              ;
              ;-----загрузка истин. MBR и передача управления ей-----------¬
              MOV   DX,0080h                      ;¬ side 0   disk 1       ¦
              MOV   CX,0007h                      ;¦ cyl  0   sect 7       ¦
              MOV   BX,7C00h                      ;¦                       ¦
              XOR   AX,AX                         ;¦                       ¦
              MOV   ES,AX                         ;+загружаем MBR по адресу¦
              MOV   AX,0201h                      ;¦       0000:7C00h      ¦
              INT   13h                           ;-                       ¦
              DB    0EAh,00,7Ch,00,00             ;JMP far 0000:7C00h      ¦
              ;-------------------------------------------------------------
              ;
              ;-----процедура обработки прерывания 13h---------------------¬
Resident13_begining:                                                       ¦
              CMP   CX,0001h                      ;¬                       ¦
              JNE   jmp_old_int13                 ;¦                       ¦
              CMP   DX,0080h                      ;¦реализация стэлс-меха- ¦
              JNE   may_by_boot                   ;¦низма: читающий сектор ¦
              CMP   AH,02                         ;¦0 0 1, получает истин. ¦
              JNE   may_by_write                  ;¦MBR                    ¦
              MOV   CX,0007h                      ;-                       ¦
              JMP   Short jmp_old_int13           ;                        ¦
              ;                                                            ¦
may_by_boot:  CMP   DX,0180h                      ;¬                       ¦
              JNE   jmp_old_int13                 ;¦                       ¦
may_by_write: CMP   AH,03                         ;¦отслеживание попытки   ¦
              JNE   jmp_old_int13                 ;¦записать что-то в      ¦
              MOV   AX,3                          ;¦сектор 0 0 1 -- MBR    ¦
              INT   10h                           ;¦или -- 0 1 1 -- BR     ¦
              PUSH  CS                            ;-                       ¦
              POP   DS                            ;¬                       ¦
              MOV   AH,9                          ;¦печать предупруждения  ¦
              MOV   DX,admonition - Code_begining ;¦о попытки записи       ¦
              INT   21h                           ;-                       ¦
              XOR   AX,AX                         ;¬ожидание нажатия клавиши
              INT   16h                           ;-                       ¦
              DB    0EAh,00,00,0FFh,0FFh          ;JMP far FFFF:0000h      ¦
jmp_old_int13:                                    ;¬здесь будет адрес старого
              ;                                   ;¦  обработчика INT 13h  ¦
              DB    0EAh,00,00,00,00              ;-JMP far ????:????h     ¦
              ;                                                            ¦
              ;                                                            ¦
admonition:   DB   'System area writing attempt !!!',0Dh,0Ah               ¦
              DB   'Remove floppy disks & press any key...$'               ¦
Resident_ending:------------------------------------------------------------
              ;
              ;
              ;
MainProcedure ENDP
              ;
CodeSegment   ENDS
              END Start


     Что здесь новенького? Новое прерывание. Прерывание BIOS INT 16h (функция
0) -- ввод с клавиатуры. Когда  дается это прерывание, PC замирает и ждет на-
жатия клавиши. После нажатия клавиши соответствующий  ASCII символ помещается
в AL, а в AH устанавливается скэн-код. В этом примере прерывание 16 использу-
ется просто  для создания паузы -- ожидание нажатия  любой клавиши. Еще здесь
показана функция 9 прерывания 21h -- печать строки символов. С  этой функцией
мы уже встречались  (см.  пример 10).  Напомним  лишь кратко, что  печатаемая
строка символов обязательно  должна заканчиваться символом "$". Ее адрес дол-
жен быть загружен в пару регистров DS:DX.
     Удивительно, с какой  легкостью  показанный выше антивирус может превра-
титься в полноценный (правда, - довольно примитивный) бутовый вирус. Изменить
надо лишь чуть-чуть. Вот блок/схема; сравните:



     --инициализационная часть-¬                 _/резидентная часть\_
------------------------------------¬   -------------------------------------¬
¦ установка стека: SS=0, SP=7C00h   ¦   ¦ читаеся сектор 0 0 1 HDD? если да -¦
¦(сам код начинается по 0000:7C00h) ¦   ¦подсовываем вместо него сектор 0 0 7¦
L-----------------T------------------   ¦(истинную MBR,загодя там сохраненную)
                  ¦                     L-----------------T-------------------
------------------+-----------------¬                     ¦
¦ уменьшаем слово по адресу 0:413h  ¦   ------------------+------------------¬
L-----------------T------------------   ¦читаееся сектор 0 0 1 дискеты? нет, ¦
                  ¦                     ¦уходим на IRET >>--------------------¬
------------------+-----------------¬   L-----------------T-------------------¦
¦ пересылаем резидент в освободив-  ¦                     ¦                   ¦
¦ шуюся область                     ¦   ------------------+------------------¬¦
L-----------------T------------------   ¦включен ли мотор дисковода? да, --  ¦¦
                  ¦                     ¦уходим на IRET >>-------------------->
------------------+-----------------¬   L-----------------T-------------------¦
¦ делаем JMP far на продолжение кода¦                     ¦                   ¦
¦ уже в резиденте                   ¦   ------------------+------------------¬¦
L-----------------T------------------   ¦записываем код вируса в сектор 0 0 1¦¦
                  ¦                     ¦дискеты                             ¦¦
------------------+-----------------¬   L-----------------T-------------------¦
¦ считываем по адресу 0000:7C00h    ¦                  ---+--¬                ¦
¦ истинную MBR (она была записана   ¦                  ¦ IRET¦<----------------
¦ в сектор 0 0 7)                   ¦                  L------
L-----------------T------------------
                  ¦
------------------+-----------------¬
¦ перехватываем вектор прерывания   ¦
¦ 13h                               ¦
L-----------------T------------------
                  ¦
------------------+-----------------¬
¦проверяем, есть ли в считанной MBR ¦
¦сигнатура вируса; если да - обходим¦
¦блок заражения >>--------------------¬
L-----------------T------------------ ¦
                  ¦                   ¦
------------------+-----------------¬ ¦
¦переписываем MBR в сектор 0 0 7    ¦ ¦
+-----------------------------------+ ¦
¦записываем код вируса в сектор 001 ¦ ¦
L-----------------T------------------ ¦
                  ¦                   ¦
------------------+-----------------¬<-
¦ делаем JMP far на 0000:7C00h      ¦
¦ (отдаем управл-е истинной MBR)    ¦
L------------------------------------

Назад | Далее




Рейтинг@Mail.ru